﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Web;
using System.Net;

using System.Threading;
using System.Windows;

using xbmc_json_async;
using xbmc_json_async.Media;
using xbmc_json_async.Library;
using xbmc_json_async.System;
using xbmc_json_async.Playlist;
using System.IO;
using Newtonsoft.Json.Linq;

namespace xbmc_json_async_test_winform
{
    public enum AudioLibraryMode
    {
        Artists,
        Albums,
        Genres
    }

    public partial class MainForm : Form
    {
        private XbmcSettings mXbmcSettings = null;

        private XConnection connection;

        private BindingSource listBoxAudioLibraryMainBindingSource = new BindingSource();
        private BindingSource listBoxAudioLibrarySecondaryBindingSource = new BindingSource();

        private BindingSource albumsBs = new BindingSource();
        private BindingSource albumSongBs = new BindingSource();

        private BindingSource artistsBs = new BindingSource();

        private bool isAudioLibraryUpdateOccuring = false;
        private bool isVideoLibraryUpdateOccuring = false;

        private AudioLibraryMode audioLibraryMode = AudioLibraryMode.Albums;

        private string ipAddress = "127.0.0.1";
        private int port = 8080;
        private int eventPort = 9090;

        private string userName = "xbmc";
        private string password = "xbmc";
        public MainForm()
        {
            InitializeComponent();

            mXbmcSettings = new XbmcSettings();

            listBoxAudioLibraryMain.DataSource = listBoxAudioLibraryMainBindingSource;
            listBoxAudioLibrarySecondary.DataSource = listBoxAudioLibrarySecondaryBindingSource;

            Connect();
        }

        private void Connect()
        {
            connection = new XConnection(mXbmcSettings.XbmcIpAddress,mXbmcSettings.XbmcIpPort,mXbmcSettings.XbmcUserName,mXbmcSettings.XbmcUserPassword);

            WireEventListener();
            
        }

        private void WireEventListener()
        {
            var eventListener = new XEventListener(mXbmcSettings.XbmcIpAddress, mXbmcSettings.XbmcEventPort);
            eventListener.OnXEventReceived += new XEventReceivedEventHandler(eventListener_OnXEventReceived);
            eventListener.Connect();
        }

        void eventListener_OnXEventReceived(object sender, XNotification type, Dictionary<string, object> parameters)
        {
            MessageBox.Show("EventListener captured event : " + type.ToString());
        }

        #region remote
        private void buttonPrevious_Click(object sender, EventArgs e)
        {
            connection.AudioPlayer.GoPrevious();
           
        }

        private void buttonMusic_Click(object sender, EventArgs e)
        {
            //connection.AudioLibrary.
        }

        private void buttonNext_Click(object sender, EventArgs e)
        {
            connection.AudioPlayer.GoNext();
        }

        private void buttonPlay_Click(object sender, EventArgs e)
        {
            connection.AudioPlayer.PlayPause();
        }
        private void buttonStop_Click(object sender, EventArgs e)
        {
            connection.AudioPlayer.Stop();
        }
        #endregion

        #region AudioLibrary

        #region utilities
        private void ListBoxAudioLibrarySecondary_Update(object dataSource, string displayMember)
        {
            //listBoxAudioLibrarySecondaryBindingSource.DataSource = dataSource;
            //if (dataSource == null) return;

            if (listBoxAudioLibrarySecondary.InvokeRequired)
            {
                listBoxAudioLibrarySecondary.Invoke(
                    new MethodInvoker(
                        delegate
                        {
                            listBoxAudioLibrarySecondary.BeginUpdate();
                            listBoxAudioLibrarySecondary.DataSource = dataSource;
                            listBoxAudioLibrarySecondary.DisplayMember = displayMember;
                            listBoxAudioLibrarySecondary.EndUpdate();

                        }

                        )
                    );
            }
        }
        private void ListBoxAudioLibraryMain_Update(object dataSource, string displayMember)
                {
                    //listBoxAudioLibraryMainBindingSource.DataSource = dataSource;
                    //if (dataSource == null) return;

                    if (listBoxAudioLibraryMain.InvokeRequired)
                    {
                        listBoxAudioLibraryMain.Invoke(
                            new MethodInvoker(
                                delegate
                                {
                                    listBoxAudioLibraryMain.BeginUpdate();
                                    listBoxAudioLibraryMain.DataSource = dataSource;
                                    listBoxAudioLibraryMain.DisplayMember = displayMember;
                                    listBoxAudioLibraryMain.EndUpdate();

                                }

                                )
                            );
                    }
                }
        #endregion
        
        #region callbacks

        private void CleanCallback(object responseData)
        {
            string message =  responseData.ToString();
        }

        private void ScanCallback(object responseData)
        {
            string message = responseData.ToString();
        }

        private void GetArtistsCallback(object responseData)
        {
            Artists artists = responseData as Artists;

            isAudioLibraryUpdateOccuring = true;

            ListBoxAudioLibraryMain_Update(artists, "label");
            ListBoxAudioLibrarySecondary_Update(null, string.Empty);

            isAudioLibraryUpdateOccuring = false;
        }
                 
        private void GetAlbumCallback(object responseData)
        {
            Songs songs = responseData as Songs;

            isAudioLibraryUpdateOccuring = true;

            ListBoxAudioLibrarySecondary_Update(songs, "title");
         
            isAudioLibraryUpdateOccuring = false;
        }
        
        private void GetAlbumsCallback(object responseData)
        {
            Albums albums = responseData as Albums;

            isAudioLibraryUpdateOccuring = true;

            ListBoxAudioLibraryMain_Update(albums, "Title");

            isAudioLibraryUpdateOccuring = false;

        }

        private void GetGenresCallback(object responseData)
        {
            Genres genres = responseData as Genres;
            isAudioLibraryUpdateOccuring = true;

            ListBoxAudioLibraryMain_Update(genres, "Label");

            isAudioLibraryUpdateOccuring = false;
        }

        private void GetGenreCallback(object responseData)
        {
            Songs songs = responseData as Songs;

            isAudioLibraryUpdateOccuring = true;

            ListBoxAudioLibrarySecondary_Update(songs, "Title");

            isAudioLibraryUpdateOccuring = false;
        }
        
        private void GetAlbumDetailsCallback(object responseData)
        {
            Album album = responseData as Album;
            if (propertyGridAudioLibrary.InvokeRequired)
            {
                propertyGridAudioLibrary.Invoke(
                    new MethodInvoker(
                        delegate
                        {
                            propertyGridAudioLibrary.SelectedObject = album;
                        }
                        )
                    );
            }


        }
        
        private void GetArtistCallback(object responseData)
        {
            Songs songs = responseData as Songs;

            isAudioLibraryUpdateOccuring = true;

            ListBoxAudioLibrarySecondary_Update(songs, "Title");

            isAudioLibraryUpdateOccuring = false;
        }
        
        private void GetArtistDetailsCallback(object responseData)
        {
            Artist artist = responseData as Artist;
            if (propertyGridAudioLibrary.InvokeRequired)
            {
                propertyGridAudioLibrary.Invoke(
                    new MethodInvoker(
                        delegate
                        {
                            propertyGridAudioLibrary.SelectedObject = artist;
                        }
                        )
                    );
            }


        }

        #endregion

        #region eventhandlers
        private void listBoxAudioLibraryMain_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!isAudioLibraryUpdateOccuring)
            {
                try
                {
                    ListBox volatileSender = (ListBox)sender;

                    switch (audioLibraryMode)
                    {
                        case AudioLibraryMode.Albums:
                            Album selectedAlbum = (Album)volatileSender.SelectedItem;

                            if (selectedAlbum != null)
                            {
                                pictureBoxAudioThumbnail.Image = selectedAlbum.ThumbnailImage;
                                pictureBoxAudioFanart.Image = selectedAlbum.FanartImage;

                                connection.AudioLibrary.GetAlbumDetails(selectedAlbum.albumid, GetAlbumDetailsCallback);
                                connection.AudioLibrary.GetSongsByAlbum(selectedAlbum.albumid, null, GetAlbumCallback, null);
                            }
                            break;

                        case AudioLibraryMode.Artists:
                            Artist selectedArtist = (Artist)volatileSender.SelectedItem;
                            if (selectedArtist != null)
                            {
                                pictureBoxAudioThumbnail.Image = selectedArtist.ThumbnailImage;
                                pictureBoxAudioFanart.Image = selectedArtist.FanartImage;

                                connection.AudioLibrary.GetSongsByArtist(selectedArtist.artistid, null, GetArtistCallback);
                                connection.AudioLibrary.GetArtistDetails(selectedArtist.artistid, GetArtistDetailsCallback);

                            }
                            break;
                        case AudioLibraryMode.Genres:
                            Genre selectedGenre = (Genre)volatileSender.SelectedItem;
                            if (selectedGenre != null)
                            {
                                SortParams artistsSort = new SortParams("title", "ascending");
                                connection.AudioLibrary.GetSongsByGenre(selectedGenre.genreid, artistsSort, GetGenreCallback);
                            }
                            break;
                    }
                    
                }
                catch (Exception) { }

            }

        }

        private void listBoxAudioLibrarySecondary_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!isAudioLibraryUpdateOccuring)
            {
                try
                {
                    ListBox volatileSender = (ListBox)sender;
                    Song selectedSong = (Song)volatileSender.SelectedItem;
                    propertyGridAudioLibrary.SelectedObject = selectedSong;

                    pictureBoxAudioThumbnail.Image = selectedSong.ThumbnailImage;
                    pictureBoxAudioFanart.Image = selectedSong.FanartImage;
                   

                }
                catch (Exception) { }
            }
        }

        private void buttonExport_Click(object sender, EventArgs e)
        {
            string exportPath = textBoxExportPath.Text;

            connection.AudioLibrary.Export(exportPath, true, true, null);
        }

        private void getAlbumsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            audioLibraryMode = AudioLibraryMode.Albums;
            connection.AudioLibrary.GetAlbums(null, GetAlbumsCallback);
        }

        private void getArtistsToolStripMenuItem_Click(object sender, EventArgs e)
        {

            audioLibraryMode = AudioLibraryMode.Artists;
            
            SortParams artistsSort = new SortParams("artist", "ascending");
            connection.AudioLibrary.GetArtists(artistsSort, GetArtistsCallback);
        }

        private void getGenresToolStripMenuItem_Click(object sender, EventArgs e)
        {
            audioLibraryMode = AudioLibraryMode.Genres;
            connection.AudioLibrary.GetGenres(GetGenresCallback);
        }
        
        private void getRecentlyAddedAlbumsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
        
        private void getRecentlyAddedSongsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void cleanToolStripMenuItem_Click(object sender, EventArgs e)
        {
            connection.AudioLibrary.Clean(CleanCallback);
        }

        private void scanToolStripMenuItem_Click(object sender, EventArgs e)
        {
            connection.AudioLibrary.Scan(ScanCallback);
        }
        #endregion
        #endregion

        #region VideoLibrary
        #region utilities
        private void listBoxVideoLibraryMain_Update(object dataSource, string displayMember)
        {

            if (listBoxVideoLibraryMain.InvokeRequired)
            {
                listBoxVideoLibraryMain.Invoke(
                    new MethodInvoker(
                        delegate
                        {
                            listBoxVideoLibraryMain.BeginUpdate();
                            listBoxVideoLibraryMain.DataSource = dataSource;
                            listBoxVideoLibraryMain.DisplayMember = displayMember;
                            listBoxVideoLibraryMain.EndUpdate();

                        }

                        )
                    );
            }
        }
        #endregion
        #region callbacks
        private void GetMoviesCallback(object responseData)
        {
            Movies movies = responseData as Movies;

            isVideoLibraryUpdateOccuring = true;

            listBoxVideoLibraryMain_Update(movies, "title");

            isVideoLibraryUpdateOccuring = false;
        }
        #endregion

        #region EventHandlers
        private void GetMoviestoolStripMenuItem_Click(object sender, EventArgs e)
        {
            connection.VideoLibrary.GetMovies(null, GetMoviesCallback);
        }
        #endregion
        #endregion

        #region JSONRPC

        #region utilities
        #endregion

        #region callbacks
        private void IntrospectCallback(object responseData)
        {
            if (textBoxOutput.InvokeRequired)
            {
                textBoxOutput.Invoke(
                    new MethodInvoker(
                        delegate
                        {
                            textBoxOutput.Text = responseData.ToString();
                        }
                        )
                    );
            }
        }

        private void NotifyAllCallback(object responseData)
        {
            if (textBoxOutput.InvokeRequired)
            {
                textBoxOutput.Invoke(
                    new MethodInvoker(
                        delegate
                        {
                            textBoxOutput.Text = "";
                            textBoxOutput.Text = responseData.ToString();
                        }
                        )
                    );
            }
        }
        #endregion

        #region eventhandlers
        private void buttonIntrospect_Click(object sender, EventArgs e)
        {
            connection.JsonRpc.Introspect(IntrospectCallback);
        }

        private void buttonNotify_Click(object sender, EventArgs e)
        {
            string senderName = textBoxNotificationSender.Text;
            string message = textBoxNotificationMessage.Text;

            connection.JsonRpc.NotifyAll(senderName, message, NotifyAllCallback);
        }

        #endregion

        
        #endregion

        #region System
        #region utilities
        #endregion

        #region callbacks
  
        #endregion

        #region eventhandlers

        #endregion
        #endregion


        

        

       









       
    }
}
